home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / ax25.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-27  |  26.1 KB  |  887 lines

  1. /*  Low level AX.25 code:
  2.  *  incoming frame processing (including digipeating)
  3.  *  IP encapsulation
  4.  *  digipeater routing
  5.  *
  6.  *  Copyright 1991 Phil Karn, KA9Q / 1991 Kevin Hil, G1EMM
  7.  */
  8. /* Mods by PA0GRI */
  9.  
  10. #include <stdio.h>
  11. #include "global.h"
  12. #include "config.h"
  13. #ifdef AX25
  14. #include "mbuf.h"
  15. #include "iface.h"
  16. #include "arp.h"
  17. #include "slip.h"
  18. #include "ax25.h"
  19. #include "lapb.h"
  20. #include "netrom.h"
  21. #include "ip.h"
  22. #include "devparam.h"
  23. #include "trace.h"
  24. #include "pktdrvr.h"
  25. #include "netuser.h"
  26. #include "commands.h"
  27. #include <ctype.h>
  28.  
  29. static int axsend __ARGS((struct iface *iface,char *dest,char *source,
  30.     int cmdrsp,int ctl,struct mbuf *data));
  31. static int axip_stop __ARGS((struct iface *iface));
  32. static int axip_raw __ARGS((struct iface *iface,struct mbuf *bp));
  33. #ifdef AUTOROUTE
  34. extern int ax25_check_corruption __ARGS((struct ax25 *header));
  35. #endif /* AUTOROUTE */
  36.  
  37. /* List of AX.25 multicast addresses in network format (shifted ascii).
  38.  * Only the first entry is used for transmissions, but any incoming
  39.  * packet with any one of these destination addresses is recognized
  40.  * as a multicast
  41.  */
  42. /* NOTE: IF you CHANGE the order of these, also change the codes in ax25.h !!!
  43.  * mailfor.c, nr3, and ax25cmd.c depend on this to get broadcast addresses !!!
  44.  * 920306 - WG7J
  45.  */
  46. char Ax25multi[][AXALEN] = {
  47.     'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* QST */
  48.     'N'<<1, 'O'<<1, 'D'<<1, 'E'<<1, 'S'<<1, ' '<<1, '0'<<1, /* NODES */
  49.     'M'<<1, 'A'<<1, 'I'<<1, 'L'<<1, ' '<<1, ' '<<1, '0'<<1, /* MAIL */
  50.     'I'<<1, 'D'<<1, ' '<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* ID */
  51.     'O'<<1, 'P'<<1, 'E'<<1, 'N'<<1, ' '<<1, ' '<<1, '0'<<1, /* OPEN */
  52.     'C'<<1, 'Q'<<1, ' '<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* CQ */
  53.     'B'<<1, 'E'<<1, 'A'<<1, 'C'<<1, 'O'<<1, 'N'<<1, '0'<<1, /* BEACON */
  54.     'R'<<1, 'M'<<1, 'N'<<1, 'C'<<1, ' '<<1, ' '<<1, '0'<<1, /* RMNC */
  55.     'A'<<1, 'L'<<1, 'L'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* ALL */
  56.     '\0',
  57. };
  58. char NOCALL[] =    {'N'<<1, 'O'<<1, 'C'<<1, 'A'<<1, 'L'<<1, 'L'<<1, '0'<<1};
  59. char Mycall[AXALEN];
  60. char MyBBS[AXALEN];
  61. #ifdef NETROM
  62. char Myalias[AXALEN];    /* the NETROM alias in 'call' form */
  63. char Nralias[ALEN+1];      /* the NETROM alias in 'alias' form */
  64. #endif
  65. #ifdef CONVERS
  66. char Ccall[AXALEN];
  67. #endif
  68. char Tcall[AXALEN];
  69. char Icall[AXALEN];
  70. char Ncall[AXALEN];
  71.  
  72. struct ax_route *Ax_routes; /* Routing table header */
  73. #ifdef AXIP
  74. static int32 axipaddr[NAX25];    /* table of IP addresses of AX.25 interfaces */
  75. #ifdef PPP
  76. extern int16 DFAR fcstab[];      /* table used when calculating FCS */
  77. #else
  78. int16 fcstab[256] = {
  79.     0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  80.     0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  81.     0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  82.     0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  83.     0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  84.     0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  85.     0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  86.     0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  87.     0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  88.     0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  89.     0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  90.     0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  91.     0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  92.     0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  93.     0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  94.     0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  95.     0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  96.     0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  97.     0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  98.     0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  99.     0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  100.     0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  101.     0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  102.     0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  103.     0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  104.     0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  105.     0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  106.     0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  107.     0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  108.     0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  109.     0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  110.     0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  111. };
  112. #endif
  113. #endif
  114.  
  115. /* Send IP datagrams across an AX.25 link */
  116. int
  117. ax_send(bp,iface,gateway,prec,del,tput,rel)
  118. struct mbuf *bp;
  119. struct iface *iface;
  120. int32 gateway;
  121. int prec;
  122. int del;
  123. int tput;
  124. int rel;
  125. {
  126.     char *hw_addr;
  127.     struct ax25_cb *axp;
  128.     struct mbuf *tbp;
  129.  
  130.     struct ax_route *axr;
  131.     char mode = AX_DEFMODE;        /* default to interface mode */
  132.  
  133.     if(gateway == iface->broadcast) /* This is a broadcast IP datagram */
  134.          return (*iface->output)(iface,Ax25multi[0],iface->ipcall,PID_IP,bp);
  135.  
  136.     if((hw_addr = res_arp(iface,ARP_AX25,gateway,bp)) == NULLCHAR)
  137.         return 0;    /* Wait for address resolution */
  138.  
  139.     /* If there's a defined route, get it */
  140.     axr = ax_lookup(hw_addr, iface);
  141.  
  142.     if(axr == NULLAXR) {
  143.         if(iface->flags & CONNECT_MODE){
  144.             mode = AX_VC_MODE;
  145.         } else {
  146.             mode = AX_DATMODE;
  147.         }
  148.     } else {
  149.         mode = axr->mode;
  150.         if(mode == AX_DEFMODE) {
  151.             if(iface->flags & CONNECT_MODE){
  152.                 mode = AX_VC_MODE;
  153.             } else {
  154.                 mode = AX_DATMODE;
  155.             }
  156.         }    
  157.     }
  158.  
  159.     /* UI frames are used for any one of the following three conditions:
  160.      * 1. The "low delay" bit is set in the type-of-service field.
  161.      * 2. The "reliability" TOS bit is NOT set and the interface is in
  162.      *    datagram mode.
  163.      * 3. The destination is the broadcast address (this is helpful
  164.      *    when broadcasting on an interface that's in connected mode).
  165.      */
  166.     if(del || (!rel && (mode == AX_DATMODE))
  167.      || addreq(hw_addr,Ax25multi[0])){
  168.         /* Use UI frame */
  169.         return (*iface->output)(iface,hw_addr,iface->ipcall,PID_IP,bp);
  170.     }
  171.  
  172.  
  173.     /* Reliability is needed; use I-frames in AX.25 connection */
  174.     if((axp = find_ax25(iface->ipcall,hw_addr,iface)) == NULLAX25){
  175.         /* Open a new connection */
  176.         axp = open_ax25(iface,iface->ipcall,hw_addr,
  177.          AX_ACTIVE,Axwindow,s_arcall,s_atcall,s_ascall,-1);
  178.         if(axp == NULLAX25){
  179.             free_p(bp);
  180.             return -1;
  181.         }
  182.     }
  183.     if(axp->state == LAPB_DISCONNECTED){
  184.         est_link(axp);
  185.         lapbstate(axp,LAPB_SETUP);
  186.     }
  187.     /* Insert the PID */
  188.     if((tbp = pushdown(bp,1)) == NULLBUF){
  189.         free_p(bp);
  190.         return -1;
  191.     }
  192.     bp = tbp;
  193.     bp->data[0] = PID_IP;
  194.     if((tbp = segmenter(bp,axp->paclen)) == NULLBUF){
  195.         free_p(bp);
  196.         return -1;
  197.     }
  198.     return send_ax25(axp,tbp,-1);
  199. }
  200. /* Add header and send connectionless (UI) AX.25 packet.
  201.  * Note that the calling order here must match enet_output
  202.  * since ARP also uses it.
  203.  */
  204. int
  205. ax_output(iface,dest,source,pid,data)
  206. struct iface *iface;    /* Interface to use; overrides routing table */
  207. char *dest;        /* Destination AX.25 address (7 bytes, shifted) */
  208. char *source;        /* Source AX.25 address (7 bytes, shifted) */
  209. int16 pid;        /* Protocol ID */
  210. struct mbuf *data;    /* Data field (follows PID) */
  211. {
  212.     struct mbuf *bp;
  213.  
  214.     /* Prepend pid to data */
  215.     bp = pushdown(data,1);
  216.     if(bp == NULLBUF){
  217.         free_p(data);
  218.         return -1;
  219.     }
  220.     bp->data[0] = (char)pid;
  221.     return axsend(iface,dest,source,LAPB_COMMAND,UI,bp);
  222. }
  223. /* Common subroutine for sendframe() and ax_output() */
  224. static int
  225. axsend(iface,dest,source,cmdrsp,ctl,data)
  226. struct iface *iface;    /* Interface to use; overrides routing table */
  227. char *dest;        /* Destination AX.25 address (7 bytes, shifted) */
  228. char *source;        /* Source AX.25 address (7 bytes, shifted) */
  229. int cmdrsp;        /* Command/response indication */
  230. int ctl;        /* Control field */
  231. struct mbuf *data;    /* Data field (includes PID) */
  232. {
  233.     struct mbuf *cbp;
  234.     struct ax25 addr;
  235.     struct ax_route *axr;
  236.     char *idest;
  237.     int rval;
  238.  
  239.     /* If the source addr is unspecified, use the interface address */
  240.     if(source[0] == '\0')
  241.         source = iface->hwaddr;
  242.  
  243.     /* If there's a digipeater route, get it */
  244.     axr = ax_lookup(dest,iface);
  245.  
  246.     memcpy(addr.dest,dest,AXALEN);
  247.     memcpy(addr.source,source,AXALEN);
  248.     addr.cmdrsp = cmdrsp;
  249.  
  250.     if(axr != NULLAXR){
  251.         memcpy(addr.digis,axr->digis,axr->ndigis*AXALEN);
  252.         addr.ndigis = axr->ndigis;
  253.         idest = addr.digis[0];
  254.     } else {
  255.         addr.ndigis = 0;
  256.         idest = dest;
  257.     }
  258.  
  259.     addr.nextdigi = 0;
  260.  
  261.     /* Allocate mbuf for control field, and fill in */
  262.     if((cbp = pushdown(data,1)) == NULLBUF){
  263.         free_p(data);
  264.         return -1;
  265.     }
  266.     cbp->data[0] = ctl;
  267.  
  268.     if((data = htonax25(&addr,cbp)) == NULLBUF){
  269.         free_p(cbp);    /* Also frees data */
  270.         return -1;
  271.     }
  272.     /* This shouldn't be necessary because redirection has already been
  273.      * done at the IP router layer, but just to be safe...
  274.      */
  275.     if(iface->forw != NULLIF){
  276. #ifdef notdef
  277.         logsrc(iface->forw,iface->forw->hwaddr);
  278. #endif
  279.         logsrc(iface->forw,source);
  280.         logdest(iface->forw,idest);
  281.         rval = (*iface->forw->raw)(iface->forw,data);
  282.     } else {
  283. #ifdef notdef
  284.         logsrc(iface,iface->hwaddr);
  285. #endif
  286.         logsrc(iface,source);
  287.         logdest(iface,idest);
  288.         rval = (*iface->raw)(iface,data);
  289.     }
  290.     return rval;
  291. }
  292. #ifdef    AXIP
  293. /* Handle AX.25 frames received inside IP according to RFC-1226 */
  294. void
  295. axip_input(iface,ip,bp,rxbroadcast)
  296. struct iface *iface;    /* Input interface */
  297. struct ip *ip;          /* IP header */
  298. struct mbuf *bp;        /* AX.25 frame with FCS */
  299. int rxbroadcast;    /* Accepted for now */
  300. {
  301.     int i;
  302.     struct mbuf *tbp;
  303.     int16 len, f, fcs = 0xffff;
  304.  
  305.     /* Since the AX.25 frame arrived on an interface that does
  306.        not necessarily support AX.25, we have to find a suitable
  307.        AX.25 interface, or drop the packet.
  308.      */
  309.     /* Try to find a matching AX.25 pseudo interface */
  310.     for(i=0; i < NAX25; ++i)
  311.          if(axipaddr[i] == ip->source)
  312.           break;
  313.     if(i == NAX25) {
  314.          /* Here we could still try to pick a real AX.25 interface,
  315.         but that would mean that we are accepting AX.25 frames
  316.         from unknown IP hosts, so we'd rather drop it.
  317.           */
  318.          free_p(bp);
  319.          return;
  320.     }
  321.     iface = Ifaces;
  322.     while (iface != NULLIF) {
  323.          if(iface->raw == axip_raw && iface->dev == i)
  324.           /* found the right AX.25 pseudo interface */
  325.           break;
  326.          iface = iface->next;
  327.     }
  328.     if(iface == NULLIF) {
  329.          free_p(bp);
  330.          return;
  331.     }
  332.     len = len_p(bp) - sizeof(fcs);
  333.     if(dup_p(&tbp,bp,0,len) != len) {
  334.          free_p(bp);
  335.          return;
  336.     }
  337.     while(len--)
  338.          fcs = (fcs >> 8) ^ fcstab[(fcs ^ PULLCHAR(&bp)) & 0x00ff];
  339.     fcs ^= 0xffff;
  340.     f = PULLCHAR(&bp);
  341.     f |= (PULLCHAR(&bp) << 8);
  342.     if(fcs == f){
  343.          /* add some tracing - WG7J */
  344. #ifdef TRACE
  345.          dump(iface,IF_TRACE_IN,CL_AX25,tbp);
  346. #endif
  347.          ax_recv(iface,tbp);
  348.     } else
  349.          free_p(tbp);
  350. }
  351. #endif
  352. /* Process incoming AX.25 packets.
  353.  * After optional tracing, the address field is examined. If it is
  354.  * directed to us as a digipeater, repeat it.  If it is addressed to
  355.  * us or to QST-0, kick it upstairs depending on the protocol ID.
  356.  */
  357. extern int16 CT4init;
  358.  
  359. void
  360. ax_recv(iface,bp)
  361. struct iface *iface;
  362. struct mbuf *bp;
  363. {
  364.     struct mbuf *hbp;
  365.     char control;
  366.     struct ax25 hdr;
  367.     struct ax25_cb *axp;
  368.     struct ax_route *axr;
  369.     struct iface *cross;
  370.     char (*mpp)[AXALEN];
  371.     int mcast;
  372.     char *isrc,*idest;  /* "immediate" source and destination */
  373.     int To_us = 0;      /* Is this a link to us ? */
  374.  
  375.     /* Pull header off packet and convert to host structure */
  376.     if(ntohax25(&hdr,&bp) < 0){
  377.         /* Something wrong with the header */
  378.         free_p(bp);
  379.         return;
  380.     }
  381. #ifdef AUTOROUTE
  382. /* Check that there are no illegal characters in the header.  If there
  383.         are, then this packet is corrupt.
  384.         To ease maintainability, put this code in ax25aar.c, where the
  385.         autoreverse IP routing code is situated.
  386.  
  387.         G4JEC  15 December 1990.
  388.     */
  389.     if(ax25_check_corruption(&hdr)){    /* If returned integer is set, then the
  390.                                         packet is corrupt.  Free the packet. */
  391.         free_p(bp);
  392.         return;
  393.     }
  394. #endif /* AUTOROUTE */
  395.  
  396.     if(iface->flags & LOG_IPHEARD) {
  397.         struct mbuf *nbp;
  398.         int pid;
  399.         struct ip ip;
  400.         int len;
  401.  
  402.         len = len_p(bp);
  403.         if(dup_p(&nbp, bp, 0, len) == len) {
  404.             /* find higher proto, if any */
  405.             (void) PULLCHAR(&nbp);  /* skip control byte */
  406.             if(PULLCHAR(&nbp) == PID_IP) {
  407.                 ntohip(&ip,&nbp);
  408.                 if(ip.version == IPVERSION)
  409.                     log_ipheard(ip.source,iface);
  410.             }
  411.         free_p(nbp);
  412.         }
  413.     }
  414.  
  415.     /* If there were digis in this packet and at least one has
  416.      * been passed, then the last passed digi is the immediate source.
  417.      * Otherwise it is the original source.
  418.      */
  419.     if(hdr.ndigis != 0 && hdr.nextdigi != 0)
  420.         isrc = hdr.digis[hdr.nextdigi-1];
  421.     else
  422.         isrc = hdr.source;
  423.  
  424.     /* If there are digis in this packet and not all have been passed,
  425.      * then the immediate destination is the next digi. Otherwise it
  426.      * is the final destination.
  427.      */
  428.     cross = NULLIF;
  429.     if(hdr.ndigis != 0 && hdr.nextdigi != hdr.ndigis){
  430.         idest = hdr.digis[hdr.nextdigi];
  431.         if(!addreq(idest,iface->hwaddr)){
  432.             /* Check if digi matches callsign of any other
  433.              * interface for crossband digipeating.
  434.              */
  435.             for(cross = Ifaces; cross != NULLIF; cross = cross->next){
  436.                 if(cross->type == CL_AX25 &&
  437.                     addreq(idest,cross->hwaddr)) {
  438.                     /* Swap callsigns so that the reply
  439.                      * can be crossband digipeated in
  440.                      * the other direction.
  441.                      */
  442.                     memcpy(idest,iface->hwaddr,AXALEN);
  443.                     break;
  444.                 }
  445.             }
  446.         }
  447.     }
  448.     else
  449.         idest = hdr.dest;
  450.  
  451.     /* Don't log our own packets if we overhear them, as they're
  452.      * already logged by axsend() and by the digipeater code.
  453.      */
  454. #ifdef NETROM
  455.     if(!addreq(isrc,iface->hwaddr) && !addreq(isrc,Nr_iface->hwaddr)){
  456. #else    
  457.     if(!addreq(isrc,iface->hwaddr) && !addreq(isrc,iface->ipcall)){
  458. #endif
  459.         logsrc(iface,isrc);
  460.         logdest(iface,idest);
  461.     }
  462.     /* Examine immediate destination for a multicast address */
  463.     mcast = 0;
  464.     for(mpp = Ax25multi;(*mpp)[0] != '\0';mpp++){
  465.         if(addreq(idest,*mpp)){
  466.             mcast = 1;
  467.             break;
  468.         }
  469.     }
  470.  
  471.     /* Now check for any connection already in the AX.25 cb list
  472.      * This allows netrom user connects (with inverted ssid's) ,
  473.      * connections already established etc.. to pass.
  474.      * There should be no more digis needed!
  475.      * Added 11/15/91 WG7J
  476.      */
  477.     if(hdr.nextdigi == hdr.ndigis)
  478.         /* See if the source and destination address are in hash table */
  479.         if((axp = find_ax25(hdr.dest,hdr.source,iface)) != NULLAX25)
  480.             To_us = KNOWN_LINK;
  481.  
  482.     /* Check to see if this is the Netrom interface callsign
  483.      * or the alias ! Accept any SSID on the alias.
  484.      * NOTE: This also allows digipeating via those calls!
  485.      * Added 11/15/91 WG7J
  486.      */
  487.     if(!To_us) {
  488. #ifdef NETROM
  489.         if(addreq(idest,Myalias))
  490.             To_us = ALIAS_LINK;     /* this is for the alias */
  491.         else
  492.           if((iface->flags & IS_NR_IFACE) && addreq(idest,Nr_iface->hwaddr))
  493.             To_us = NETROM_LINK;    /* this is for the netrom callsign! */
  494.         else
  495. #endif
  496.           if(addreq(idest,iface->hwaddr))
  497.             To_us = IFACE_LINK;     /* this is to the interface call */
  498. #ifdef CONVERS
  499.         else if(addreq(hdr.dest,Ccall) && (iface->flags & IS_CONV_IFACE))
  500.             To_us = CONF_LINK;      /* this is for the conference call */
  501. #endif
  502. #ifdef TUTOR
  503.         else if(addreq(hdr.dest,Tcall))
  504.             To_us = TUTOR_LINK;      /* this is for the tutor server call */
  505.         else if(addreq(hdr.dest,Icall))
  506.             To_us = INFO_LINK;      /* this is for the info server call */
  507.         else if(addreq(hdr.dest,Ncall))
  508.             To_us = NEWS_LINK;      /* this is for the news server call */
  509. #endif
  510.     else if (addreq(idest,MyBBS))
  511.         To_us = ALIAS_LINK;
  512.     }
  513.     if (addreq(idest,iface->ipcall))    {
  514.         To_us |= IP_LINK;
  515.             if (To_us & KNOWN_LINK)
  516.             axp->jumpstarted = To_us;
  517.         }
  518.     if(!To_us && !mcast && !cross){
  519.         /* Not a broadcast, and not addressed to us. Inhibit
  520.          * transmitter to avoid colliding with addressed station's
  521.          * response, and discard packet.
  522.          */
  523. #ifdef notdef
  524.         if(iface->ioctl != NULL){
  525.             (*iface->ioctl)(iface,PARAM_MUTE,1,-1L);
  526.         }
  527. #endif
  528.         free_p(bp);
  529.         return;
  530.     }
  531.  
  532. #ifdef notdef
  533.     if(!mcast && !cross && iface->ioctl != NULL){
  534.         /* Packet was sent to us; abort transmit inhibit */
  535.         (*iface->ioctl)(iface,PARAM_MUTE,1,0L);
  536.     }
  537. #endif
  538.     /* At this point, packet is either addressed to us, or is
  539.      * a multicast.
  540.      */
  541.         if(addreq(hdr.source,NOCALL))    {    /* don't even acknowledge NOCALL's */
  542.         free_p(bp);
  543.         return;
  544.     }
  545.     if(hdr.nextdigi < hdr.ndigis)    {    /* Packet requests digipeating. See if we can repeat it. */
  546.             if((iface->flags & AX25_DIGI) && !mcast)    {
  547.             /* Yes, kick it back out. htonax25 will set the
  548.              * repeated bit.
  549.              */
  550.             hdr.nextdigi++;
  551.             if(cross)   /* Crossband digipeat */
  552.                 iface = cross;
  553.             if(iface->flags & AX25_DIGI) {
  554.                 if((hbp = htonax25(&hdr,bp)) != NULLBUF)    {
  555.                     logsrc(iface,iface->hwaddr);
  556.                     if(iface->forw != NULLIF)    {
  557.                         logdest(iface->forw,hdr.digis[hdr.nextdigi]);
  558.                                     (*iface->forw->raw)(iface->forw,hbp);
  559.                     } else {
  560.                         logdest(iface,hdr.digis[hdr.nextdigi]);
  561.                                     (*iface->raw)(iface,hbp);
  562.                     }
  563.                     bp = NULLBUF;
  564.                 }
  565.             }
  566.         }
  567.         free_p(bp);    /* Dispose if not forwarded */
  568.         return;
  569.     }
  570.     /* If we reach this point, then the packet has passed all digis,
  571.      * and is either addressed to us or is a multicast
  572.      */
  573.     if(bp == NULLBUF){
  574.         return;         /* Nothing left */
  575.     }
  576.  
  577.     /* If there's no locally-set entry in the routing table and
  578.      * this packet has digipeaters, create or update it. Leave
  579.      * local routes alone.
  580.      */
  581.     if(((axr = ax_lookup(hdr.source,iface)) == NULLAXR || axr->type == AX_AUTO)
  582.      && hdr.ndigis > 0){
  583.         char digis[MAXDIGIS][AXALEN];
  584.         int i,j;
  585.  
  586.         /* Construct reverse digipeater path */
  587.         for(i=hdr.ndigis-1,j=0;i >= 0;i--,j++){
  588.             memcpy(digis[j],hdr.digis[i],AXALEN);
  589.             digis[j][ALEN] &= ~(E|REPEATED);
  590.         }
  591.         ax_add(hdr.source,AX_AUTO,digis,hdr.ndigis,iface);
  592.     }
  593.     /* Sneak a peek at the control field. This kludge is necessary because
  594.      * AX.25 lacks a proper protocol ID field between the address and LAPB
  595.      * sublayers; a control value of UI indicates that LAPB is to be
  596.      * bypassed.
  597.      */
  598.     control = *bp->data & ~PF;
  599.  
  600.     if(uchar(control) == UI){
  601.         int pid;
  602.         struct axlink *ipp;
  603.  
  604.         (void) PULLCHAR(&bp);
  605.         if((pid = PULLCHAR(&bp)) == -1)
  606.             return;        /* No PID */
  607.         /* Find network level protocol and hand it off */
  608.         for(ipp = Axlink;ipp->funct != NULL;ipp++){
  609.             if(ipp->pid == pid)
  610.                 break;
  611.         }
  612.         if(ipp->funct != NULL)
  613.             (*ipp->funct)(iface,NULLAX25,hdr.source,hdr.dest,bp,mcast);
  614.         else
  615.             free_p(bp);
  616.         return;
  617.     }
  618.     /* Everything from here down is connected-mode LAPB, so ignore
  619.      * multicasts
  620.      */
  621.     if(mcast){
  622.         free_p(bp);
  623.         return;
  624.     }
  625.     /* At this point, if we already have a connection on its way,
  626.      * we already have found the control block !
  627.      * 11/15/91 WG7J/PA3DIS
  628.      */
  629.     if(!(To_us & KNOWN_LINK)) {
  630.         /* This is a new connection to either the interface call,
  631.          * or to the BBS call or the BBS alias or the INFO call
  632.          * or the NEWS call or the TUTOR call or the IPCALL,
  633.          * or to the netrom-interface call or system alias.
  634.          * Create a new ax25 entry for this guy,
  635.          * insert into hash table keyed on his address,
  636.          * and initialize table entries
  637.          */
  638.            if((axp = cr_ax25(hdr.dest,hdr.source,iface)) == NULLAX25){
  639.             free_p(bp);
  640.             return;
  641.         }
  642. #ifdef CONVERS
  643.            /* set a different T4 if conference link - WG7J */
  644.         if(To_us == CONF_LINK)
  645.                set_timer(&axp->t4,CT4init * 1000L);
  646. #endif
  647.         axp->jumpstarted = To_us;
  648.         if(hdr.cmdrsp == LAPB_UNKNOWN)
  649.             axp->proto = V1;    /* Old protocol in use */
  650.     }
  651.     lapb_input(axp,hdr.cmdrsp,bp);
  652. }
  653.  
  654. /* General purpose AX.25 frame output */
  655. int
  656. sendframe(axp,cmdrsp,ctl,data)
  657. struct ax25_cb *axp;
  658. int cmdrsp;
  659. int ctl;
  660. struct mbuf *data;
  661. {
  662.     return axsend(axp->iface,axp->remote,axp->local,cmdrsp,ctl,data);
  663. }
  664. /* Find a route for an AX.25 address
  665.  * Code to remove SSID field C/R- and E-bits in ax_lookup(), ax_add() and
  666.  * ax_drop() added by vk6zjm 4/5/92. This eliminates duplicate AX25 routes.
  667.  * 1992-05-28 - Added interface -- sm6rpz
  668.  */
  669.  
  670. struct ax_route *
  671. ax_lookup(target,ifp)
  672. char *target;
  673. struct iface *ifp;
  674. {
  675.     register struct ax_route *axr;
  676.     struct ax_route *axlast = NULLAXR;
  677.     char xtarget[AXALEN];
  678.  
  679.     /* Remove C/R and E bits in local copy only */
  680.     memcpy(xtarget,target,AXALEN);
  681.     xtarget[AXALEN-1] &= SSID;
  682.  
  683.     for(axr = Ax_routes; axr != NULLAXR; axlast = axr,axr = axr->next){
  684. /*        if(memcmp(axr->target,target,AXALEN) == 0){    */
  685.         if(addreq(axr->target,xtarget) && axr->iface == ifp)    {
  686.             if(axr != Ax_routes){
  687.                 /* Move entry to top of list to speed
  688.                  * future searches
  689.                  */
  690.                 axlast->next = axr->next;
  691.                 axr->next = Ax_routes;
  692.                 Ax_routes = axr;
  693.  
  694.             }
  695.             return axr;
  696.         }
  697.     }
  698.     return axr;
  699. }
  700. /* Add an entry to the AX.25 routing table */
  701. struct ax_route *
  702. ax_add(target,type,digis,ndigis,ifp)
  703. char *target;
  704. int type;
  705. char digis[][AXALEN];
  706. int ndigis;
  707. struct iface *ifp;
  708. {
  709.     register struct ax_route *axr;
  710.     char xtarget[AXALEN];
  711.  
  712.     if(ndigis < 0 || ndigis > MAXDIGIS || addreq(target,ifp->hwaddr) || addreq(target,ifp->ipcall))
  713.         return NULLAXR;
  714.  
  715.     /* Remove C/R and E bits in local copy only */
  716.     memcpy(xtarget,target,AXALEN);
  717.     xtarget[AXALEN-1] &= SSID;
  718.  
  719.     if((axr = ax_lookup(xtarget,ifp)) == NULLAXR){
  720.         axr = (struct ax_route *)callocw(1,sizeof(struct ax_route));
  721.         axr->next = Ax_routes;
  722.         Ax_routes = axr;
  723.         memcpy(axr->target,xtarget,AXALEN);
  724.         axr->ndigis = ndigis;
  725.         axr->iface = ifp;
  726.         axr->mode = AX_DEFMODE;        /* set mode to default */
  727.     }
  728.     axr->type = type;
  729.     if(axr->ndigis != ndigis)
  730.         axr->ndigis = ndigis;
  731.  
  732.     memcpy(axr->digis,digis[0],ndigis*AXALEN);
  733.     return axr;
  734. }
  735. int
  736. ax_drop(target,ifp)
  737. char *target;
  738. struct iface *ifp;
  739. {
  740.     register struct ax_route *axr;
  741.     struct ax_route *axlast = NULLAXR;
  742.     char xtarget[AXALEN];
  743.  
  744.     /* Remove C/R and E bits in local copy only */
  745.     memcpy(xtarget,target,AXALEN);
  746.     xtarget[AXALEN-1] &= SSID;
  747.  
  748.     for(axr = Ax_routes;axr != NULLAXR;axlast=axr,axr = axr->next)
  749. /*        if(memcmp(axr->target,target,AXALEN) == 0)    */
  750.         if(addreq(axr->target,xtarget) && axr->iface == ifp)    
  751.             break;
  752.     if(axr == NULLAXR)
  753.         return -1;    /* Not in table! */
  754.     if(axlast != NULLAXR)
  755.         axlast->next = axr->next;
  756.     else
  757.         Ax_routes = axr->next;
  758.  
  759.     free((char *)axr);
  760.     return 0;
  761. }
  762. /* Handle ordinary incoming data (no network protocol) */
  763. void
  764. axnl3(iface,axp,src,dest,bp,mcast)
  765. struct iface *iface;
  766. struct ax25_cb *axp;
  767. char *src;
  768. char *dest;
  769. struct mbuf *bp;
  770. int mcast;
  771. {
  772.     if(axp == NULLAX25){
  773.         free_p(bp);
  774.         /* beac_input(iface,src,bp); */
  775.     } else {
  776.         append(&axp->rxq,bp);
  777.         if(axp->r_upcall != NULLVFP)
  778.             (*axp->r_upcall)(axp,len_p(axp->rxq));
  779.     }
  780. }
  781.  
  782. #ifdef    AXIP
  783. /* attach a fake AX.25 interface for AX.25 on top of IP */
  784. /* argv[0] == "axip"
  785.  * argv[1] == name of new interface
  786.  * argv[2] == MTU
  787.  * argv[3] == hostname of remote end of wormhole
  788.  * argv[4] == optional AX.25 callsign for this interface, must be specified
  789.  *          and be different from any other interface callsign if crossband
  790.  *             digipeating is going to work properly
  791.  */
  792. int
  793. axip_attach(argc,argv,p)
  794. int argc;
  795. char *argv[];
  796. void *p;
  797. {
  798.      int i;
  799.      struct iface *ifp;
  800.  
  801.      /* Check for too long iface names - WG7J */
  802.      if(strlen(argv[1]) >= ILEN) {
  803.         tprintf("interface max %d chars\n",ILEN-1);
  804.         return -1;
  805.      }
  806.      if(if_lookup(argv[1]) != NULLIF) {
  807.       tprintf("interface %s already attached\n",argv[1]);
  808.       return -1;
  809.      }
  810.      for(i=0; i < NAX25; ++i)
  811.       if(axipaddr[i] == 0)
  812.            break;
  813.      if(i == NAX25) {
  814.       tprintf("too many AX25 interfaces attached\n");
  815.       return -1;
  816.      }
  817.      if((axipaddr[i] = resolve(argv[3])) == 0) {
  818.       tprintf("invalid address\n");
  819.       return -1;
  820.      }
  821.      ifp = (struct iface *)callocw(1,sizeof(struct iface));
  822.      ifp->dev = i;
  823.      ifp->addr = Ip_addr;
  824.      ifp->name = strdup(argv[1]);
  825.      ifp->hwaddr = mallocw(AXALEN);
  826.      memcpy(ifp->hwaddr,Mycall,AXALEN);
  827.      ifp->ipcall = mallocw(AXALEN);
  828.      memcpy(ifp->ipcall,Mycall,AXALEN);
  829.      ifp->mtu = atoi(argv[2]);
  830.      setencap(ifp,"AX25");
  831.      if(argc > 4) {
  832.            free (ifp->hwaddr);
  833.            free (ifp->ipcall);
  834.       ifp->hwaddr = mallocw(ifp->iftype->hwalen);
  835.       (*ifp->iftype->scan)(ifp->hwaddr,argv[4]);
  836.       ifp->ipcall = mallocw(ifp->iftype->hwalen);
  837.       (*ifp->iftype->scan)(ifp->ipcall,argv[4]);
  838.      }
  839.      ifp->raw = axip_raw;
  840.      ifp->stop = axip_stop;
  841.      ifp->next = Ifaces;
  842.      Ifaces = ifp;
  843.      return 0;
  844. }
  845. static int
  846. axip_stop(iface)
  847. struct iface *iface;
  848. {
  849.      axipaddr[iface->dev] = 0;
  850.      return 0;
  851. }
  852.  
  853. /* raw routine for sending AX.25 on top of IP */
  854. static int
  855. axip_raw(iface,bp)
  856. struct iface *iface;    /* Pointer to interface control block */
  857. struct mbuf *bp;        /* Data field */
  858. {
  859.      int16 len, fcs = 0xffff;
  860.      struct mbuf *bp1;
  861.  
  862.      dump(iface,IF_TRACE_OUT,iface->type,bp);
  863.      iface->rawsndcnt++;
  864.      iface->lastsent = secclock();
  865.      len = len_p(bp);
  866.      if(dup_p(&bp1,bp,0,len) != len) {
  867.       free_p(bp);
  868.       return -1;
  869.      }
  870.      while (len--)        /* calculate FCS */
  871.       fcs = (fcs >> 8) ^ fcstab[(fcs ^ PULLCHAR(&bp1)) & 0x00ff];
  872.  
  873.      fcs ^= 0xffff;    /* final FCS (is this right?) */
  874.      if((bp1 = alloc_mbuf(sizeof (fcs))) == NULLBUF) {
  875.       free_p(bp);
  876.       return -1;
  877.      }
  878.      *bp1->data = fcs & 0xff;
  879.      *(bp1->data+1) = (fcs >> 8) & 0xff;
  880.      bp1->cnt += sizeof(fcs);
  881.      append(&bp,bp1);
  882.      return ip_send(INADDR_ANY,axipaddr[iface->dev],AX25_PTCL,0,0,bp,0,0,0);
  883. }
  884. #endif
  885.  
  886. #endif /* AX25 */
  887.